// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Buffers;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using BenchmarkDotNet.Attributes;
using Nethermind.Core.Extensions;
using Nethermind.Evm;
using Nethermind.Evm.CodeAnalysis;

namespace Nethermind.Benchmarks.Evm;

public class JumpDestinationsBenchmark
{
    const string x0000_48KiB = "0x0000..48KiB";
    const string x5b00_48KiB = "0x5b00..48KiB";
    const string x005b_256KiB = "0x005b..256KiB";
    const string x5b5b_512KiB = "0x5b5b..512KiB";
    const string x6060_48KiB = "0x6060..48KiB";
    const string x6500_48KiB = "0x6500..48KiB";
    const string x715b_48KiB = "0x715b..48KiB";
    const string x5b71_48KiB = "0x5b71..48KiB";
    const string x7f5b_256KiB = "0x7f5b..256KiB";
    const string x5b7f_512KiB = "0x5b7f..512KiB";
    const string SmallContract = "SmallContract";
    const string MediumContract = "MediumContract";
    const string UniSwapV4 = "UniSwapV4";

    private static Dictionary<string, byte[]> _codeLookup = new()
    {
        [x0000_48KiB] = CreateCode(49152, 0x00, 0x00),
        [x5b00_48KiB] = CreateCode(49152, 0x5b, 0x00),
        [x005b_256KiB] = CreateCode(262144, 0x00, 0x5b),
        [x5b5b_512KiB] = CreateCode(524288, 0x5b, 0x5b),
        [x6060_48KiB] = CreateCode(49152, 0x60, 0x60),
        [x6500_48KiB] = CreateCode(49152, 0x65, 0x00),
        [x715b_48KiB] = CreateCode(49152, 0x71, 0x5b),
        [x5b71_48KiB] = CreateCode(49152, 0x5b, 0x71),
        [x7f5b_256KiB] = CreateCode(262144, 0x7f, 0x5b),
        [x5b7f_512KiB] = CreateCode(524288, 0x5b, 0x7f),
        [SmallContract] = Bytes.FromHexString("60606040525b600080fd00a165627a7a7230582012c9bd00152fa1c480f6827f81515bb19c3e63bf7ed9ffbb5fda0265983ac7980029"),
        [MediumContract] = Bytes.FromHexString("0x608060405234801561001057600080fd5b506040516040806119738339810180604052604081101561003057600080fd5b50805160209091015160008054600160a060020a0319163317808255604051600160a060020a039190911691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600160a060020a03821615156100f957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f43616e6e6f742073657420666565206163636f756e7420746f203078302e0000604482015290519081900360640190fd5b606460ff82161115610156576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806119526021913960400191505060405180910390fd5b6002805460ff909216740100000000000000000000000000000000000000000260a060020a60ff0219600160a060020a03909416600160a060020a031990931692909217929092161790556117a2806101b06000396000f3fe6080604052600436106100fa576000357c0100000000000000000000000000000000000000000000000000000000900480638f32d59b1161009c578063d0386d9711610076578063d0386d971461035e578063f2fde38b14610433578063fc17e94014610473578063fffc780114610527576100fa565b80638f32d59b1461027b578063a001ecdd146102a4578063c48f28ed146102cf576100fa565b806365e17c9d116100d857806365e17c9d146101e25780636e9fb85114610220578063715018a6146102515780638da5cb5b14610266576100fa565b80633d4dff7b146100ff5780634b023cf81461015d5780634cc537cd1461019f575b600080fd5b34801561010b57600080fd5b506101296004803603602081101561012257600080fd5b5035610572565b604080516bffffffffffffffffffffffff909416845263ffffffff9283166020850152911682820152519081900360600190f35b34801561016957600080fd5b5061019d6004803603602081101561018057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166105c1565b005b3480156101ab57600080fd5b506101c9600480360360208110156101c257600080fd5b50356106bc565b6040805163ffffffff9092168252519081900360200190f35b3480156101ee57600080fd5b506101f76106e4565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61019d6004803603606081101561023657600080fd5b5080359063ffffffff60208201358116916040013516610700565b34801561025d57600080fd5b5061019d61093e565b34801561027257600080fd5b506101f76109ef565b34801561028757600080fd5b50610290610a0b565b604080519115158252519081900360200190f35b3480156102b057600080fd5b506102b9610a29565b6040805160ff9092168252519081900360200190f35b3480156102db57600080fd5b5061019d600480360360e08110156102f257600080fd5b5080359063ffffffff60208201358116916bffffffffffffffffffffffff60408201351691606082013516906fffffffffffffffffffffffffffffffff196080820135169073ffffffffffffffffffffffffffffffffffffffff60a082013581169160c0013516610a4a565b34801561036a57600080fd5b5061019d600480360361018081101561038257600080fd5b60408051808201825283359363ffffffff60208201358116946bffffffffffffffffffffffff8584013516946060840135909216936fffffffffffffffffffffffffffffffff196080850135169373ffffffffffffffffffffffffffffffffffffffff60a082013581169460c08301359091169382019261012083019160e084019060029083908390808284376000920191909152509194505060ff82351692505060208101359060400135610ca2565b34801561043f57600080fd5b5061019d6004803603602081101561045657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166111b0565b34801561047f57600080fd5b5061019d600480360361016081101561049757600080fd5b5080359063ffffffff60208201358116916bffffffffffffffffffffffff6040820135169160608201358116916fffffffffffffffffffffffffffffffff196080820135169173ffffffffffffffffffffffffffffffffffffffff60a083013581169260c08101359092169160ff60e0820135169161010082013591610120810135916101409091013516611209565b34801561053357600080fd5b506105516004803603602081101561054a57600080fd5b5035611556565b604080516bffffffffffffffffffffffff9092168252519081900360200190f35b6001602052600090815260409020546bffffffffffffffffffffffff81169063ffffffff6c01000000000000000000000000820481169170010000000000000000000000000000000090041683565b6105c9610a0b565b151561060e576040516000805160206116de83398151915281526004018080602001828103825260268152602001806116886026913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116151561068057604080516000805160206116de833981519152815260206004820152601e60248201527f43616e6e6f742073657420666565206163636f756e7420746f203078302e0000604482015290519081900360640190fd5b6002805473ffffffffffffffffffffffffffffffffffffffff191673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000908152600160205260409020546c01000000000000000000000000900463ffffffff1690565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b8215801590610714575063ffffffff821615155b801561072f57508163ffffffff163481151561072c57fe5b06155b80156107485750346bffffffffffffffffffffffff1634145b15156107a357604080516000805160206116de833981519152815260206004820152601a60248201527f496e76616c696420696e70757420746f2066756e6374696f6e2e000000000000604482015290519081900360640190fd5b4263ffffffff8216116107ef576040516000805160206116de833981519152815260040180806020018281038252602a81526020018061174d602a913960400191505060405180910390fd5b6000838152600160205260409020546c01000000000000000000000000900463ffffffff161561086e57604080516000805160206116de833981519152815260206004820152601960248201527f6465706f736974494420616c7265616479206578697374732e00000000000000604482015290519081900360640190fd5b5050604080516060810182526bffffffffffffffffffffffff348116825263ffffffff42811660208085019182526000858701818152978152600190915294909420925183549451955182167001000000000000000000000000000000000273ffffffff0000000000000000000000000000000019969092166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff919093166bffffffffffffffffffffffff1990951694909417939093161792909216179055565b610946610a0b565b151561098b576040516000805160206116de83398151915281526004018080602001828103825260268152602001806116886026913960400191505060405180910390fd5b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36000805473ffffffffffffffffffffffffffffffffffffffff19169055565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b60005473ffffffffffffffffffffffffffffffffffffffff16331490565b60025474010000000000000000000000000000000000000000900460ff1681565b6040805160208082018a90527c010000000000000000000000000000000000000000000000000000000063ffffffff808b16820284860152740100000000000000000000000000000000000000006bffffffffffffffffffffffff8b1602604485015288160260508301526fffffffffffffffffffffffffffffffff19861660548301526c0100000000000000000000000073ffffffffffffffffffffffffffffffffffffffff80871682026064850152339190910260788401528351606c818503018152608c9093018452825192820192909220600081815260019092529290209083161515610b8a57604080516000805160206116de833981519152815260206004820152601d60248201527f526566756e64546f20616464726573732063616e6e6f7420626520302e000000604482015290519081900360640190fd5b805460006bffffffffffffffffffffffff909116118015610bd85750428663ffffffff16111580610bd85750805463ffffffff89811670010000000000000000000000000000000090920416145b1515610c1d576040516000805160206116de833981519152815260040180806020018281038252602a8152602001806116fe602a913960400191505060405180910390fd5b805460405173ffffffffffffffffffffffffffffffffffffffff8516916bffffffffffffffffffffffff1680156108fc02916000818181858888f19350505050158015610c6e573d6000803e3d6000fd5b50506000908152600160205260409020805473ffffffffffffffffffffffffffffffffffffffff1916905550505050505050565b6040805160208082018e90527c010000000000000000000000000000000000000000000000000000000063ffffffff8e8116820284860152740100000000000000000000000000000000000000006bffffffffffffffffffffffff8f160260448501528c8116820260508501526fffffffffffffffffffffffffffffffff198c1660548501526c0100000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8c8116820260648701528b1690810260788601528551606c818703018152608c86018752805190850120600081815260018087528882208d518e89015160ac8b01869052908716880260cc8b015290951690950260d0880152875180880360b401815260d48801808a5281519188019190912091905260f487018089525260ff8a1661011487015261013486018990526101548601889052955191949093610174808301939192601f198301929081900390910190855afa158015610e14573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff16141515610e7a576040516000805160206116de83398151915281526004018080602001828103825260258152602001806117286025913960400191505060405180910390fd5b4263ffffffff8b1611610ec6576040516000805160206116de833981519152815260040180806020018281038252602a81526020018061174d602a913960400191505060405180910390fd5b8551815463ffffffff91821670010000000000000000000000000000000090910490911611801590610f0757506020860151865163ffffffff918216911611155b8015610f1f5750602086015163ffffffff8d81169116105b1515610f7a57604080516000805160206116de833981519152815260206004820152601260248201527f496e76616c696420756e69742072616e67650000000000000000000000000000604482015290519081900360640190fd5b6000610fc1610fb56bffffffffffffffffffffffff8e168984602002015163ffffffff168a6001602002015163ffffffff1603600101611576565b8e63ffffffff166115aa565b90506000610feb610fe483600260149054906101000a900460ff1660ff16611576565b60646115aa565b90506000610ff983836115ce565b9050826bffffffffffffffffffffffff16831480156110255750806bffffffffffffffffffffffff1681145b151561108057604080516000805160206116de833981519152815260206004820152601c60248201527f43617374696e6720636175736564206c6f7373206f6620646174612e00000000604482015290519081900360640190fd5b801561119e5760405173ffffffffffffffffffffffffffffffffffffffff8c169082156108fc029083906000818181858888f193505050501580156110c9573d6000803e3d6000fd5b5081156111195760025460405173ffffffffffffffffffffffffffffffffffffffff9091169083156108fc029084906000818181858888f19350505050158015611117573d6000803e3d6000fd5b505b8354611133906bffffffffffffffffffffffff16846115ce565b84546bffffffffffffffffffffffff19166bffffffffffffffffffffffff919091161784558860016020020151845473ffffffff000000000000000000000000000000001916700100000000000000000000000000000000600190920163ffffffff16919091021784555b50505050505050505050505050505050565b6111b8610a0b565b15156111fd576040516000805160206116de83398151915281526004018080602001828103825260268152602001806116886026913960400191505060405180910390fd5b611206816115e3565b50565b6040805160208082018e90527c010000000000000000000000000000000000000000000000000000000063ffffffff808f16820284860152740100000000000000000000000000000000000000006bffffffffffffffffffffffff8f160260448501528c160260508301526fffffffffffffffffffffffffffffffff198a1660548301526c0100000000000000000000000073ffffffffffffffffffffffffffffffffffffffff808b1682026064850152339190910260788401528351606c818503018152608c909301845282519282019290922060008181526001909252929020908316151561134957604080516000805160206116de833981519152815260206004820152601d60248201527f526566756e64546f20616464726573732063616e6e6f7420626520302e000000604482015290519081900360640190fd5b805460006bffffffffffffffffffffffff90911611801561136f5750428763ffffffff16105b801561138057508963ffffffff1642105b15156113c5576040516000805160206116de83398151915281526004018080602001828103825260308152602001806116ae6030913960400191505060405180910390fd5b6040805160208082018590527c010000000000000000000000000000000000000000000000000000000063ffffffff8b16028284015282516024818403018152604483018085528151918301919091206000909152606483018085525260ff8916608483015260a4820188905260c48201879052915173ffffffffffffffffffffffffffffffffffffffff8b169260019260e480820193601f1981019281900390910190855afa15801561147d573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff161415156114e3576040516000805160206116de83398151915281526004018080602001828103825260258152602001806117286025913960400191505060405180910390fd5b805460405173ffffffffffffffffffffffffffffffffffffffff8516916bffffffffffffffffffffffff1680156108fc02916000818181858888f19350505050158015611534573d6000803e3d6000fd5b5080546bffffffffffffffffffffffff19169055505050505050505050505050565b6000908152600160205260409020546bffffffffffffffffffffffff1690565b6000821515611587575060006115a4565b82820282848281151561159657fe5b04146115a157600080fd5b90505b92915050565b60008082116115b857600080fd5b600082848115156115c557fe5b04949350505050565b6000828211156115dd57600080fd5b50900390565b73ffffffffffffffffffffffffffffffffffffffff8116151561160557600080fd5b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff191673ffffffffffffffffffffffffffffffffffffffff9290921691909117905556fe4f6e6c7920746865206f776e65722063616e2063616c6c20746869732066756e6374696f6e2e496e73756666696369656e7420726571756972656d656e747320746f20636c61696d206561726c7920726566756e642e08c379a000000000000000000000000000000000000000000000000000000000496e73756666696369656e7420726571756972656d656e747320746f20636c61696d20726566756e642e5369676e617475726520696e636f727265637420666f7220676976656e2076616c7565732e65787069727954696d657374616d70206d757374206265203e20626c6f636b2e74696d657374616d702ea165627a7a723058203285db6b1a0de8377c6b1a934a045aecb19a4d34b010b227c67b1fa3b12a9d8e002943616e6e6f742068617665206665652070657263656e74616765203e203130302e0000000000000000000000002b5ad5c4795c026514f8317c7a215e218dccd6cf0000000000000000000000000000000000000000000000000000000000000014"),
        [UniSwapV4] = Bytes.FromHexString("0x60a0806040526004361015610012575f80fd5b5f3560e01c908162fdd58e14612cd55750806301ffc9a714612c16578063095bcdb614612b6c5780630b0d9c0914612ae057806311da60b414612a85578063156e29f6146129d55780631e2eaeaf1461299b578063234266d7146126fc5780632d7713891461265157806335fd631a146125dd5780633dd45adb14612579578063426a8493146124f557806348c894911461226a5780635275965114612152578063558a72971461207b578063598af9e714611fe35780635a6bcfda1461144f5780636276cbbe14610f965780637e87ce7d14610e5957806380f0b44c14610d875780638161b87414610c315780638da5cb5b14610be157806397e8cd4e14610b7e5780639bf6645f14610b31578063a584119414610a66578063b6363cf2146109d5578063dbd035ff1461097f578063f02de3b21461092e578063f135baaa146108f4578063f2fde38b14610848578063f3cd914c146104ff578063f5298aca146103345763fe99049a14610186575f80fd5b346103305760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330576101bd612d3f565b6101c5612d62565b90604435917f1b3d7edb2e9c0b0e7c525b20aaaef0f5940d2ed71663c7d39266ecafac72885961027973ffffffffffffffffffffffffffffffffffffffff80606435951693843314158061030d575b610287575b845f52600460205260405f20875f5260205260405f2061023a878254612fed565b90551693845f52600460205260405f20865f5260205260405f2061025f828254612ffa565b905560408051338152602081019290925290918291820190565b0390a4602060405160018152f35b845f52600560205260405f208233165f5260205260405f20875f5260205260405f2054867fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036102da575b5050610219565b6102e391612fed565b855f52600560205260405f208333165f5260205260405f20885f5260205260405f20555f866102d3565b50845f52600360205260405f208233165f5260205260ff60405f20541615610214565b5f80fd5b346103305761034236612d85565b7fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d7577f1b3d7edb2e9c0b0e7c525b20aaaef0f5940d2ed71663c7d39266ecafac7288596103ed73ffffffffffffffffffffffffffffffffffffffff805f9516956103bb6103b3866130aa565b3390896130f0565b169233841415806104a0575b6103f2575b8385526004602052604085208686526020526040852061025f828254612fed565b0390a4005b83855260056020526040852073ffffffffffffffffffffffffffffffffffffffff33168652602052604085208686526020526040852054817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610459575b50506103cc565b61046291612fed565b84865260056020526040862073ffffffffffffffffffffffffffffffffffffffff331687526020526040862087875260205260408620558681610452565b5083855260036020526040852073ffffffffffffffffffffffffffffffffffffffff3316865260205260ff604086205416156103c7565b7f54e3ca0d000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610330576101207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305761053836612e81565b60607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5c360112610330576040519061056f82612df6565b60a4358015158103610330578252602082019060c435825260e4359073ffffffffffffffffffffffffffffffffffffffff8216820361033057604084019182526101043567ffffffffffffffff8111610330576105d0903690600401612f4d565b9290937fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d75761060261350f565b51156108205760a0822092835f52600660205260405f209061062382613576565b60808401958482828a8a5173ffffffffffffffffffffffffffffffffffffffff169361064e94613b44565b90949195606088015160020b908b511515905173ffffffffffffffffffffffffffffffffffffffff1691604051986106858a612e12565b895260208901526040880152606087015262ffffff166080860152885115155f149862ffffff6107a2986106db61078f9860209d6108005773ffffffffffffffffffffffffffffffffffffffff8b511695614959565b9492968291926107d3575b505073ffffffffffffffffffffffffffffffffffffffff845116938e6fffffffffffffffffffffffffffffffff60408301511691015160020b90604051958860801d600f0b875288600f0b60208801526040870152606086015260808501521660a08301527f40e9cecb9f5f1f1c5b9c97dec2917b7ee92e57ba5563708daca94dd84ad7112f60c03393a38673ffffffffffffffffffffffffffffffffffffffff8a5116613d81565b809491946107aa575b5050823391613652565b604051908152f35b73ffffffffffffffffffffffffffffffffffffffff6107cc9251169083613652565b8480610798565b73ffffffffffffffffffffffffffffffffffffffff165f5260018f5260405f209081540190558e806106e6565b73ffffffffffffffffffffffffffffffffffffffff8e8c01511695614959565b7fbe8b8507000000000000000000000000000000000000000000000000000000005f5260045ffd5b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330577fffffffffffffffffffffffff00000000000000000000000000000000000000006108a0612d3f565b73ffffffffffffffffffffffffffffffffffffffff5f54916108c58284163314613007565b1691829116175f55337f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3005b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330576004355c5f5260205ff35b34610330575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057602073ffffffffffffffffffffffffffffffffffffffff60025416604051908152f35b346103305761098d36612f7b565b6040519160408360208152836020820152019160051b8301916020806040850193925b83355481520191019084838210156109cc5750602080916109b0565b60408186030190f35b346103305760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057610a0c612d3f565b73ffffffffffffffffffffffffffffffffffffffff610a29612d62565b91165f52600360205273ffffffffffffffffffffffffffffffffffffffff60405f2091165f52602052602060ff60405f2054166040519015158152f35b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057610a9d612d3f565b73ffffffffffffffffffffffffffffffffffffffff81169081610ae15750505f7f27e098c505d44ec3574004bca052aabf76bd35004c182099d8c575fb238593b95d005b610aea90613a92565b907f27e098c505d44ec3574004bca052aabf76bd35004c182099d8c575fb238593b95d7f1e0745a7db1623981f0b2a5d4232364c00787266eb75ad546f190e6cebe9bd955d005b3461033057610b3f36612f7b565b6040519160408360208152836020820152019160051b8301916020806040850193925b83355c81520191019084838210156109cc575060208091610b62565b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305773ffffffffffffffffffffffffffffffffffffffff610bca612d3f565b165f526001602052602060405f2054604051908152f35b34610330575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057602073ffffffffffffffffffffffffffffffffffffffff5f5416604051908152f35b346103305760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057610c68612d3f565b610c70612d62565b60443573ffffffffffffffffffffffffffffffffffffffff600254163303610d5f5773ffffffffffffffffffffffffffffffffffffffff821680151580610d1f575b610cf7576020936107a29280610cef5750815f526001855260405f20549384925b5f526001865260405f20610ce8848254612fed565b90556131f8565b938492610cd3565b7fc79e5948000000000000000000000000000000000000000000000000000000005f5260045ffd5b508073ffffffffffffffffffffffffffffffffffffffff7f27e098c505d44ec3574004bca052aabf76bd35004c182099d8c575fb238593b95c1614610cb2565b7f48f5c3ed000000000000000000000000000000000000000000000000000000005f5260045ffd5b346103305760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057610dbe612d3f565b7fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d757335f90815273ffffffffffffffffffffffffffffffffffffffff8216602052604090205c610e146024356130aa565b9081600f0b03610e3157610e2f9133915f03600f0b906130f0565b005b7fbda73abf000000000000000000000000000000000000000000000000000000005f5260045ffd5b346103305760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057610e9136612e81565b610e99612e6f565b9073ffffffffffffffffffffffffffffffffffffffff600254163303610d5f57623e900062fff0008316106103e9610fff8416101615610f6557602060a07fe9c42593e71f84403b84352cd168d693e2c9fcd1fdbcc3feb21d92b43e6696f9922092835f526006825260405f20610f0f81613576565b805479ffffff00000000000000000000000000000000000000000000008360b81b16907fffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffff1617905562ffffff60405191168152a2005b62ffffff827fa7abe2f7000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b346103305760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057610fce36612e81565b60a4359073ffffffffffffffffffffffffffffffffffffffff821680830361033057610ff861350f565b6060820191825160020b617fff81136114245750825160020b600181126113f9575073ffffffffffffffffffffffffffffffffffffffff815116602082019073ffffffffffffffffffffffffffffffffffffffff825116808210156113c2575050608082019073ffffffffffffffffffffffffffffffffffffffff82511690604084019161108c62ffffff845116826139b7565b1561139757506110a162ffffff835116613a75565b96835173ffffffffffffffffffffffffffffffffffffffff8116908133036112e0575b505060a0852090815f52600660205260405f2090815473ffffffffffffffffffffffffffffffffffffffff166112b8576020997fdd466e674ea557f56295e2d0218a125ea4b4f0f6f3307b95f85e6110838d6438927cffffff000000000000000000000000000000000000000000000000000061114260a0946145fc565b9260d01b168a76ffffff000000000000000000000000000000000000000084861b161717905562ffffff73ffffffffffffffffffffffffffffffffffffffff808a5116965116965116995160020b73ffffffffffffffffffffffffffffffffffffffff885116906040519b8c528c8c015260408b01528860608b015260020b98896080820152a45173ffffffffffffffffffffffffffffffffffffffff8116908133036111f4575b8585604051908152f35b61100016611203575b806111ea565b6112af9261128d604051937f6fe7e6eb0000000000000000000000000000000000000000000000000000000088860152336024860152604485019073ffffffffffffffffffffffffffffffffffffffff6080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b60e48301528361010483015261010482526112aa61012483612e2e565b613f25565b508280806111fd565b7f7983c051000000000000000000000000000000000000000000000000000000005f5260045ffd5b612000166112ef575b806110c4565b61139090604051907fdc98354e00000000000000000000000000000000000000000000000000000000602083015233602483015261137a604483018973ffffffffffffffffffffffffffffffffffffffff6080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b8860e483015260e482526112aa61010483612e2e565b50886112e9565b7fe65af6a0000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b60449250604051917f6e6c983000000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b7fe9e90588000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b7fb70024f8000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b34610330576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305761148836612e81565b60807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5c36011261033057604051906114bf82612dda565b60a4358060020b810361033057825260c4358060020b810361033057602083015260e43560408301526101043560608301526101243567ffffffffffffffff811161033057611512903690600401612f4d565b90927fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d75761154361350f565b60a0832093845f52600660205260405f20608052611562608051613576565b608084015173ffffffffffffffffffffffffffffffffffffffff811690813303611ede575b5050815160020b92602083015160020b916115a56040850151613785565b93606087015160020b9760608201516040519960c08b018b811067ffffffffffffffff821117611eb157604052338b528860208c01528660408c015287600f0b60608c015260808b015260a08a01525f9185881215611e7a577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276188812611e4e57620d89e88613611e22576040519261163c84612dda565b5f84525f60208501525f60408501525f606085015287600f0b611b25575b600460805101978960020b5f528860205260405f20988860020b5f5260205260405f206080515460a01c60020b8b81125f14611acf575060028060018c0154600184015490039b015491015490039b5b60a073ffffffffffffffffffffffffffffffffffffffff825116910151906040519160268301528960068301528b600383015281525f603a600c83012091816040820152816020820152525f5260066080510160205260405f20976fffffffffffffffffffffffffffffffff8954169982600f0b155f14611a72578a15611a4a5761176f61176960409f9b61184e9c6118609e5b60018301956117616002611755848a548503615703565b95019283548503615703565b9655556130aa565b916130aa565b6fffffffffffffffffffffffffffffffff169060801b179a8b965f84600f0b126119dc575b5082600f0b611898575b5050506117c46117b58560801d8360801d01613785565b9185600f0b90600f0b01613785565b6fffffffffffffffffffffffffffffffff169060801b1791815160020b90602083015160020b8c8401516060850151918e5194855260208501528d84015260608301527ff208f4912782fd25c7f114ca3723a2d5dd6f3bcc3ac8db5af63baa85f711d5ec60803393a38873ffffffffffffffffffffffffffffffffffffffff60808201511661385b565b8094919461186c575b50833391613652565b82519182526020820152f35b6118929073ffffffffffffffffffffffffffffffffffffffff6080840151169083613652565b85611857565b60805154929350909173ffffffffffffffffffffffffffffffffffffffff81169060a01c60020b828112156118fe575050906118f2926118e76118dd6118ed94614158565b91600f0b92614158565b90614527565b613785565b60801b5b8b808061179e565b92809193125f146119a95761193d9161192a6118ed6118ed9361192488600f0b91614158565b87614527565b9361193886600f0b92614158565b6144ca565b6fffffffffffffffffffffffffffffffff169060801b17906fffffffffffffffffffffffffffffffff61197c60036080510192600f0b8284541661456e565b167fffffffffffffffffffffffffffffffff000000000000000000000000000000008254161790556118f6565b906118ed9250926119bf6118dd6119c595614158565b906144ca565b6fffffffffffffffffffffffffffffffff166118f6565b808f9151611a1e575b01516119f2575b8e611794565b611a198260805160049160020b5f52016020525f6002604082208281558260018201550155565b6119ec565b611a458360805160049160020b5f52016020525f6002604082208281558260018201550155565b6119e5565b7faefeb924000000000000000000000000000000000000000000000000000000005f5260045ffd5b61176f61176960409f9b61184e9c6118609e6fffffffffffffffffffffffffffffffff611aa289600f0b8361456e565b167fffffffffffffffffffffffffffffffff0000000000000000000000000000000084541617835561173e565b9099908913611af55760028060018c0154600184015490039b015491015490039b6116aa565b9860026001608051015460018c01549003600183015490039a81806080510154910154900391015490039b6116aa565b6004608051018960020b5f5280602052898960405f20611b7e81546fffffffffffffffffffffffffffffffff611b6181831695600f0b8661456e565b16931594858515141595611dee575b508d600f0b9060801d613d3a565b60801b82179055602087015285528760020b5f5260205260405f208054906fffffffffffffffffffffffffffffffff8216611bbc8b600f0b8261456e565b901592836fffffffffffffffffffffffffffffffff831615141593611dc1575b8b600f0b9060801d600f0b03916f7fffffffffffffffffffffffffffffff83137fffffffffffffffffffffffffffffffff80000000000000000000000000000000841217611d9457826fffffffffffffffffffffffffffffffff935060801b83831617905516606086015260408501525f88600f0b1215611ca1575b8351611c85575b60408401511561165a57611c8060808c015160020b8860056080510161410c565b61165a565b611c9c60808c015160020b8a60056080510161410c565b611c5f565b60808b015160020b6fffffffffffffffffffffffffffffffff600181602088015116925f817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276180712817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618050390620d89e8050301810416809111611d68576fffffffffffffffffffffffffffffffff6060860151161115611c5857867fb8e3c385000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b897fb8e3c385000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b6080515460a01c60020b8b13611bdc57600160805101546001840155600260805101546002840155611bdc565b6080515460a01c60020b1215611e05575b8e611b70565b600160805101546001840155600260805101546002840155611dff565b857f1ad777f8000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b877fd5e2f7ab000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b60448887604051917fc4433ed500000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f604085015113808091611fd6575b15611f6b5750506040517f259982e5000000000000000000000000000000000000000000000000000000006020820152611f62916112aa82611f368887898c33602487016136cb565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101845283612e2e565b505b8580611587565b159081611fc8575b50611f7f575b50611f64565b6040517f21d0ee70000000000000000000000000000000000000000000000000000000006020820152611fc1916112aa82611f368887898c33602487016136cb565b5085611f79565b610200915016151587611f73565b5061080082161515611eed565b346103305760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305761201a612d3f565b73ffffffffffffffffffffffffffffffffffffffff612037612d62565b91165f52600560205273ffffffffffffffffffffffffffffffffffffffff60405f2091165f5260205260405f206044355f52602052602060405f2054604051908152f35b346103305760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330576120b2612d3f565b602435908115158092036103305773ffffffffffffffffffffffffffffffffffffffff90335f52600360205260405f208282165f5260205260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541660ff851617905560405192835216907fceb576d9f15e4e200fdb5096d64d5dfd667e16def20c1eefd14256d8e3faa26760203392a3602060405160018152f35b346103305760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305761218a36612e81565b612192612e6f565b906280000062ffffff60408301511614801590612246575b61221e5760a0906121ba8361368e565b205f52600660205260405f20906121d082613576565b81547fffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffff1660d09190911b7cffffff000000000000000000000000000000000000000000000000000016179055005b7f30d21641000000000000000000000000000000000000000000000000000000005f5260045ffd5b5073ffffffffffffffffffffffffffffffffffffffff6080820151163314156121aa565b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305760043567ffffffffffffffff8111610330576122b9903690600401612f4d565b7fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c6124cd57612345915f9160017fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235d60405193849283927f91dd734600000000000000000000000000000000000000000000000000000000845260206004850152602484019161306c565b038183335af19081156124c2575f9161241a575b507f7d4b3164c6e45b97e7d87b7125a44c5828d005af88f9d751cfd78729c5d99a0b5c6123f25760406020915f7fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f835194859381855280519182918282880152018686015e5f85828601015201168101030190f35b7f5212cba1000000000000000000000000000000000000000000000000000000005f5260045ffd5b90503d805f833e61242b8183612e2e565b8101906020818303126103305780519067ffffffffffffffff8211610330570181601f820112156103305780519067ffffffffffffffff8211611eb1576040519261249e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8601160185612e2e565b8284526020838301011161033057815f9260208093018386015e8301015281612359565b6040513d5f823e3d90fd5b7f5090d6c6000000000000000000000000000000000000000000000000000000005f5260045ffd5b346103305773ffffffffffffffffffffffffffffffffffffffff61251836612d85565b91929092335f52600560205260405f208282165f5260205260405f20845f526020528260405f205560405192835216907fb3fd5071835887567a0671151121894ddccc2842f1d10bedad13e0d17cace9a760203392a4602060405160018152f35b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330576125ab612d3f565b7fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d7576107a260209161342d565b346103305760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330576024356004356040519160408360208152826020820152019060051b8301916001602060408501935b835481520191019084838210156109cc57506020600191612635565b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305773ffffffffffffffffffffffffffffffffffffffff61269d612d3f565b6126ab825f54163314613007565b16807fffffffffffffffffffffffff000000000000000000000000000000000000000060025416176002557fb4bd8ef53df690b9943d3318996006dbb82a25f54719d8c8035b516a2a5b8acc5f80a2005b34610330576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305761273536612e81565b60c4359060a43560e43567ffffffffffffffff81116103305761275c903690600401612f4d565b9190937fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d75761278e61350f565b60a0842094855f52600660205260405f20946127a986613576565b60808101805173ffffffffffffffffffffffffffffffffffffffff811690813303612943575b50506fffffffffffffffffffffffffffffffff60038801541697881561291b576020986127fb876130aa565b5f03612806876130aa565b5f036fffffffffffffffffffffffffffffffff169060801b179887612907575b866128f2575b5050612839338985613652565b60405190868252858a8301527f29ef05caaff9404b7cb6d1c0e9bbae9eaa7ab2541feba1a9c4248594c08156cb60403393a3519273ffffffffffffffffffffffffffffffffffffffff841693843303612897575b8888604051908152f35b6010166128a5575b8061288d565b6128e6956112aa93611f36926040519788957fe1b4af69000000000000000000000000000000000000000000000000000000008d88015233602488016135bc565b5082808080808061289f565b600201908660801b048154019055898061282c565b60018101828960801b048154019055612826565b7fa74f97ab000000000000000000000000000000000000000000000000000000005f5260045ffd5b602016612951575b806127cf565b6040517fb6a8b0fa000000000000000000000000000000000000000000000000000000006020820152612994916112aa82611f368b898b8d8b33602488016135bc565b508861294b565b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057600435545f5260205ff35b34610330576129e336612d85565b907fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d7577f1b3d7edb2e9c0b0e7c525b20aaaef0f5940d2ed71663c7d39266ecafac7288596103ed73ffffffffffffffffffffffffffffffffffffffff805f941695612a62612a55876130aa565b8603600f0b3390896130f0565b16938484526004602052604084208685526020526040842061025f828254612ffa565b5f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330577fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d75760206107a23361342d565b346103305760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033057612b17612d3f565b612b1f612d62565b604435907fc090fc4683624cfc3884e9d8de5eca132f2d0ec062aff75d43c0465d5ceeab235c156104d757610e2f92612b67612b5a846130aa565b5f03600f0b3390836130f0565b6131f8565b346103305773ffffffffffffffffffffffffffffffffffffffff612b8f36612d85565b91929092335f52600460205260405f20845f5260205260405f20612bb4848254612fed565b90551690815f52600460205260405f20835f5260205260405f20612bd9828254612ffa565b9055604080513380825260208201939093527f1b3d7edb2e9c0b0e7c525b20aaaef0f5940d2ed71663c7d39266ecafac7288599181908101610279565b346103305760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610330576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361033057807f01ffc9a70000000000000000000000000000000000000000000000000000000060209214908115612cab575b506040519015158152f35b7f0f632fb30000000000000000000000000000000000000000000000000000000091501482612ca0565b346103305760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103305760209073ffffffffffffffffffffffffffffffffffffffff612d24612d3f565b165f526004825260405f206024355f52825260405f20548152f35b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361033057565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361033057565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60609101126103305760043573ffffffffffffffffffffffffffffffffffffffff8116810361033057906024359060443590565b6080810190811067ffffffffffffffff821117611eb157604052565b6060810190811067ffffffffffffffff821117611eb157604052565b60a0810190811067ffffffffffffffff821117611eb157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117611eb157604052565b60a4359062ffffff8216820361033057565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60a09101126103305760405190612eb882612e12565b8160043573ffffffffffffffffffffffffffffffffffffffff8116810361033057815260243573ffffffffffffffffffffffffffffffffffffffff8116810361033057602082015260443562ffffff811681036103305760408201526064358060020b81036103305760608201526084359073ffffffffffffffffffffffffffffffffffffffff821682036103305760800152565b9181601f840112156103305782359167ffffffffffffffff8311610330576020838186019501011161033057565b9060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103305760043567ffffffffffffffff811161033057826023820112156103305780600401359267ffffffffffffffff84116103305760248460051b83010111610330576024019190565b91908203918211611d9457565b91908201809211611d9457565b1561300e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152fd5b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe093818652868601375f8582860101520116010190565b6f800000000000000000000000000000008110156130c857600f0b90565b7f93dafdf1000000000000000000000000000000000000000000000000000000005f5260045ffd5b9190600f0b9182156131f357613126919073ffffffffffffffffffffffffffffffffffffffff8092165f521660205260405f2090565b613132815c9283613b29565b80915d6131a357507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f7d4b3164c6e45b97e7d87b7125a44c5828d005af88f9d751cfd78729c5d99a0b5c017f7d4b3164c6e45b97e7d87b7125a44c5828d005af88f9d751cfd78729c5d99a0b5d5b565b156131aa57565b60017f7d4b3164c6e45b97e7d87b7125a44c5828d005af88f9d751cfd78729c5d99a0b5c017f7d4b3164c6e45b97e7d87b7125a44c5828d005af88f9d751cfd78729c5d99a0b5d565b505050565b90919073ffffffffffffffffffffffffffffffffffffffff811690816132ea5750505f80808093855af11561322a5750565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f3d011673ffffffffffffffffffffffffffffffffffffffff604051927f90bfb8650000000000000000000000000000000000000000000000000000000084521660048301525f6024830152608060448301528060a00160648301523d60848301523d5f60a484013e7ff4b3b1bc0000000000000000000000000000000000000000000000000000000060c4828401600460a4820152015260e40190fd5b60205f60448194968260409573ffffffffffffffffffffffffffffffffffffffff988751998a947fa9059cbb00000000000000000000000000000000000000000000000000000000865216600485015260248401525af13d15601f3d116001855114161716928281528260208201520152156133635750565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f3d0116604051917f90bfb86500000000000000000000000000000000000000000000000000000000835260048301527fa9059cbb000000000000000000000000000000000000000000000000000000006024830152608060448301528060a00160648301523d60848301523d5f60a484013e7ff27f64e40000000000000000000000000000000000000000000000000000000060c4828401600460a4820152015260e40190fd5b7f27e098c505d44ec3574004bca052aabf76bd35004c182099d8c575fb238593b95c919073ffffffffffffffffffffffffffffffffffffffff8316613482576131a19034935b61347c856130aa565b906130f0565b346134e7576131a1906134be7f1e0745a7db1623981f0b2a5d4232364c00787266eb75ad546f190e6cebe9bd955c6134b986613a92565b612fed565b935f7f27e098c505d44ec3574004bca052aabf76bd35004c182099d8c575fb238593b95d613473565b7fb0ec849e000000000000000000000000000000000000000000000000000000005f5260045ffd5b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000004444c5dc75cb358380d2e3de08a9016300361354e57565b7f0d89438e000000000000000000000000000000000000000000000000000000005f5260045ffd5b5473ffffffffffffffffffffffffffffffffffffffff161561359457565b7f486aa307000000000000000000000000000000000000000000000000000000005f5260045ffd5b91926136376101209473ffffffffffffffffffffffffffffffffffffffff61364f999794168552602085019073ffffffffffffffffffffffffffffffffffffffff6080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b60c083015260e082015281610100820152019161306c565b90565b9073ffffffffffffffffffffffffffffffffffffffff60206131a1949361368185848351168660801d906130f0565b01511690600f0b906130f0565b62ffffff16620f424081116136a05750565b7f14002113000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b9061364f95936137486101609473ffffffffffffffffffffffffffffffffffffffff61377794168552602085019073ffffffffffffffffffffffffffffffffffffffff6080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b8051600290810b60c08501526020820151900b60e0840152604081015161010084015260600151610120830152565b81610140820152019161306c565b9081600f0b9182036130c857565b926138419061381261364f99979473ffffffffffffffffffffffffffffffffffffffff6101a09895168752602087019073ffffffffffffffffffffffffffffffffffffffff6080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b8051600290810b60c08701526020820151900b60e0860152604081015161010086015260600151610120850152565b61014083015261016082015281610180820152019161306c565b939590919296945f9673ffffffffffffffffffffffffffffffffffffffff861633146139ac57885f6040870151135f1461393b5761040087166138a2575b50505050505050565b61392e9799985092613927969594926138ef9261391b956040519788967f9f063efc0000000000000000000000000000000000000000000000000000000060208901523360248901613793565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282612e2e565b6002821615159161459f565b80926145bf565b915f808080808080613899565b95949392919061010086166139535750505050505050565b61392e979950869850916138ef916139a09493613927986040519788967f6c2bbe7e0000000000000000000000000000000000000000000000000000000060208901523360248901613793565b6001821615159161459f565b505f96505050505050565b608081161580613a69575b613a3f57604081161580613a5d575b613a3f5761040081161580613a51575b613a3f5761010081161580613a45575b613a3f5773ffffffffffffffffffffffffffffffffffffffff8116613a1f575062ffffff1662800000141590565b613fff161590811591613a30575090565b62800000915062ffffff161490565b50505f90565b506001811615156139f1565b506002811615156139e1565b506004811615156139d1565b506008811615156139c2565b6280000062ffffff821614613a8d5761364f8161368e565b505f90565b73ffffffffffffffffffffffffffffffffffffffff1680613ab257504790565b6020602491604051928380927f70a082310000000000000000000000000000000000000000000000000000000082523060048301525afa9081156124c2575f91613afa575090565b90506020813d602011613b21575b81613b1560209383612e2e565b81010312610330575190565b3d9150613b08565b9190915f8382019384129112908015821691151617611d9457565b6020830151955f9586959194913373ffffffffffffffffffffffffffffffffffffffff851614613d2d5760808416613b7e575b5050505050565b613c66926138ef613c6092613c4c946040519586947f575e24b4000000000000000000000000000000000000000000000000000000006020870152336024870152613c16604487018c73ffffffffffffffffffffffffffffffffffffffff6080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b8051151560e487015260208101516101048701526040015173ffffffffffffffffffffffffffffffffffffffff16610124860152565b61014061014485015261016484019161306c565b82613f25565b916060835103613d05576040015162ffffff166280000014613cf9575b600816613c94575b80808080613b77565b604001519250608083901d600f0b8015613c8b57613cb5905f861295613b29565b9315613cf1575f84135b613cc9575f613c8b565b7ffa0b71d6000000000000000000000000000000000000000000000000000000005f5260045ffd5b5f8412613cbf565b60608201519350613c83565b7f1e048e1d000000000000000000000000000000000000000000000000000000005f5260045ffd5b505f965086955050505050565b90600f0b90600f0b01907fffffffffffffffffffffffffffffffff8000000000000000000000000000000082126f7fffffffffffffffffffffffffffffff831317611d9457565b9196959394929473ffffffffffffffffffffffffffffffffffffffff83163314613f18578460801d94600f0b938860408516613e40575b50505050505f9481600f0b15801590613e34575b613dd8575b5050509190565b613e0f9395505f60208201511290511515145f14613e17576fffffffffffffffffffffffffffffffff169060801b175b80936145bf565b5f8080613dd1565b906fffffffffffffffffffffffffffffffff169060801b17613e08565b5082600f0b1515613dcc565b613efc613f08946138ef6118ed95613f0e999895613ee1613c16966040519788967fb47b2fb1000000000000000000000000000000000000000000000000000000006020890152336024890152604488019073ffffffffffffffffffffffffffffffffffffffff6080809282815116855282602082015116602086015262ffffff6040820151166040860152606081015160020b6060860152015116910152565b8c61014485015261016061016485015261018484019161306c565b6004821615159161459f565b90613d3a565b5f80808088613db8565b5050505050909150905f90565b9190918251925f8060208301958682865af115613fc3575050604051917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f3d011683016040523d83523d9060208401915f833e6020845110918215613f8f575b5050613d0557565b5190517fffffffff000000000000000000000000000000000000000000000000000000009182169116141590505f80613f87565b5183517fffffffff00000000000000000000000000000000000000000000000000000000811691600481106140d7575b50507fffffffff000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f3d01169173ffffffffffffffffffffffffffffffffffffffff604051947f90bfb865000000000000000000000000000000000000000000000000000000008652166004850152166024830152608060448301528060a00160648301523d60848301523d5f60a484013e7fa9e35b2f0000000000000000000000000000000000000000000000000000000060c4828401600460a4820152015260e40190fd5b7fffffffff000000000000000000000000000000000000000000000000000000009250829060040360031b1b16168280613ff3565b919060020b9060020b9081810761413a5705908160081d5f52602052600160ff60405f2092161b8154189055565b601c906044926040519163d4d8f3e683526020830152604082015201fd5b60020b908160ff1d82810118620d89e8811161449e5763ffffffff9192600182167001fffcb933bd6fad37aa2d162d1a59400102700100000000000000000000000000000000189160028116614482575b60048116614466575b6008811661444a575b6010811661442e575b60208116614412575b604081166143f6575b608081166143da575b61010081166143be575b61020081166143a2575b6104008116614386575b610800811661436a575b611000811661434e575b6120008116614332575b6140008116614316575b61800081166142fa575b6201000081166142de575b6202000081166142c3575b6204000081166142a8575b620800001661428f575b5f12614268575b0160201c90565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04614261565b6b048a170391f7dc42444e8fa290910260801c9061425a565b6d2216e584f5fa1ea926041bedfe9890920260801c91614250565b916e5d6af8dedb81196699c329225ee6040260801c91614245565b916f09aa508b5b7a84e1c677de54f3e99bc90260801c9161423a565b916f31be135f97d08fd981231505542fcfa60260801c9161422f565b916f70d869a156d2a1b890bb3df62baf32f70260801c91614225565b916fa9f746462d870fdf8a65dc1f90e061e50260801c9161421b565b916fd097f3bdfd2022b8845ad8f792aa58250260801c91614211565b916fe7159475a2c29b7443b29c7fa6e889d90260801c91614207565b916ff3392b0822b70005940c7a398e4b70f30260801c916141fd565b916ff987a7253ac413176f2b074cf7815e540260801c916141f3565b916ffcbe86c7900a88aedcffc83b479aa3a40260801c916141e9565b916ffe5dee046a99a2a811c461f1969c30530260801c916141df565b916fff2ea16466c96a3843ec78b326b528610260801c916141d6565b916fff973b41fa98c081472e6896dfb254c00260801c916141cd565b916fffcb9843d60f6159c9db58835c9266440260801c916141c4565b916fffe5caca7e10e4e61c3624eaa0941cd00260801c916141bb565b916ffff2e50f5f656932ef12357cf3c7fdcc0260801c916141b2565b916ffff97272373d413259a46990580e213a0260801c916141a9565b827f8b86327a000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b905f83600f0b125f146144ff576144f5925f036fffffffffffffffffffffffffffffffff1691615a3d565b5f81126130c85790565b61451b926fffffffffffffffffffffffffffffffff16916159e2565b5f81126130c8575f0390565b905f83600f0b125f14614552576144f5925f036fffffffffffffffffffffffffffffffff1691615b34565b61451b926fffffffffffffffffffffffffffffffff1691615a7d565b906fffffffffffffffffffffffffffffffff90600f0b911601908160801c61459257565b6393dafdf15f526004601cfd5b906145a991613f25565b9015613a8d576040815103613d05576040015190565b6145e2906145d48360801d8260801d03613785565b92600f0b90600f0b03613785565b6fffffffffffffffffffffffffffffffff169060801b1790565b73fffd8963efd1fc6a506488495d951d516396168273ffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffd895d830116116148e05777ffffffffffffffffffffffffffffffffffffffff000000008160201b168060ff61467983615bdb565b1691608083106148d457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8182011c5b800280607f1c8160ff1c1c800280607f1c8160ff1c1c800280607f1c8160ff1c1c800280607f1c8160ff1c1c800280607f1c8160ff1c1c800280607f1c8160ff1c1c80029081607f1c8260ff1c1c80029283607f1c8460ff1c1c80029485607f1c8660ff1c1c80029687607f1c8860ff1c1c80029889607f1c8a60ff1c1c80029a8b607f1c8c60ff1c1c80029c8d80607f1c9060ff1c1c800260cd1c6604000000000000169d60cc1c6608000000000000169c60cb1c6610000000000000169b60ca1c6620000000000000169a60c91c6640000000000000169960c81c6680000000000000169860c71c670100000000000000169760c61c670200000000000000169660c51c670400000000000000169560c41c670800000000000000169460c31c671000000000000000169360c21c672000000000000000169260c11c674000000000000000169160c01c67800000000000000016907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800160401b1717171717171717171717171717693627a301d71055774c85027ffffffffffffffffffffffffffffffffffd709b7e5480fba5a50fed5e62ffc556810160801d60020b906fdb2df09e81959a81455e260799a0632f0160801d60020b918282145f146148915750905090565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff6148c584614158565b16116148cf575090565b905090565b905081607f031b6146a9565b73ffffffffffffffffffffffffffffffffffffffff907f61487524000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b811561492c570490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b6040519290915f61496985612df6565b5f855260208501925f845260408601955f875280968654956040860151159586155f146156f557610fff8860b81c16945b8151925f948a73ffffffffffffffffffffffffffffffffffffffff16918288528b60a01c60020b90526fffffffffffffffffffffffffffffffff60038d0154169052608083015162400000811615155f146156e65762bfffff166149fd8161368e565b61ffff88166156cb575b8096620f424062ffffff8316101561569a575b8451156156845750508861562457606083019073ffffffffffffffffffffffffffffffffffffffff825116818110156155ed5750505173ffffffffffffffffffffffffffffffffffffffff166401000276a38111156155c257505b604051986101008a018a811067ffffffffffffffff821117611eb1576040525f8a525f60208b01525f60408b01525f60608b01525f60808b01525f60a08b01525f60c08b015288155f146155b45760018b0154949390945b60e08b01525b8015801561557a575b6154205788868d8c8e73ffffffffffffffffffffffffffffffffffffffff8351168252602083015160020b602089015160020b90815f8183071291050386155f14615275576fffffffffffffffffffffffffffffffff937ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2761860409460019484600560ff60609716938260020b60081d890b5f5201602052875f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8460ff031c9054169283151593845f146152635790614bb760ff92615bdb565b90031660020b900360020b0260020b5b905b15158684015260020b8060208401521315615238575b620d89e8602082015160020b121561522a575b73ffffffffffffffffffffffffffffffffffffffff614c17602083015160020b614158565b16918291015273ffffffffffffffffffffffffffffffffffffffff8551169673ffffffffffffffffffffffffffffffffffffffff60608c0151169283911516818310189118021892015116928d73ffffffffffffffffffffffffffffffffffffffff8316821015915f87125f1461507f5762ffffff8516620f424003614c9f81895f03615785565b94841561506e57614cb1888483615a7d565b955b868110614fb257509660a093929173ffffffffffffffffffffffffffffffffffffffff98978891620f424062ffffff8316145f14614f9e575050865b955b15614f905791614d0092615a3d565b925b60c0820152015260808d0152168c525f8351135f14614f605760a08a0151905f82126130c8570392614d3d60808b015160c08c015190612ffa565b5f81126130c8578103908113600116611d9457935b61ffff8716614f18575b6fffffffffffffffffffffffffffffffff60408d01511680614efe575b5073ffffffffffffffffffffffffffffffffffffffff8c511673ffffffffffffffffffffffffffffffffffffffff60608c01511681145f14614ec2575060408a0151614e10575b88614e03577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208b015160020b0160020b5b60020b60208d01525b9392614ad3565b60208a015160020b614df3565b88614e96576fffffffffffffffffffffffffffffffff614e7d8d8d8d600460e08201519260206002820154935b015160020b60020b5f520160205260405f2091600183019081549003905560028201908154900390555460801d908c15614e88575b60400151831661456e565b1660408d0152614dc0565b5f91909103600f0b90614e72565b6fffffffffffffffffffffffffffffffff614e7d8d8d8d6004600183015492602060e084015193614e3d565b73ffffffffffffffffffffffffffffffffffffffff8b51168103614ee7575b50614dfc565b614ef0906145fc565b60020b60208d01525f614ee1565b60c08b015160801b0460e08b01510160e08b01525f614d79565b9662ffffff861661ffff881603614f435760c08a0151905b8160c08c01510360c08c01520196614d5c565b620f424060808b015161ffff89169060c08d015101020490614f30565b60808a015160c08b015101905f82126130c857019260a08a01515f81126130c857614f8a91613b29565b93614d52565b614f9992615b34565b614d00565b62ffffff614fad921689615c68565b614cef565b9650505092505082918415811517615061578e60a09173ffffffffffffffffffffffffffffffffffffffff96845f14614ffc57614ff0878284615d07565b80978a015f0395614cf1565b87871161503a576150356150306150286fffffffffffffffffffffffffffffffff84168a60601b614922565b8a8516612ffa565b615d9b565b614ff0565b61503561503061505c6fffffffffffffffffffffffffffffffff84168a61588a565b615028565b634f2461b85f526004601cfd5b6150798882856159e2565b95614cb3565b9193509190831561521957615095858284615a3d565b915b8287106150f7579073ffffffffffffffffffffffffffffffffffffffff9560a09280965b156150e857916150ca92615a7d565b925b6150e362ffffff8d16620f42408190039086615c68565b614d02565b6150f1926159e2565b926150cc565b50915050838315821517615061578d83156151ef575073ffffffffffffffffffffffffffffffffffffffff851161519c578460601b6fffffffffffffffffffffffffffffffff851680820615159104015b73ffffffffffffffffffffffffffffffffffffffff8316928184111561518f578f939573ffffffffffffffffffffffffffffffffffffffff60a093819803165b80966150bb565b634323a5555f526004601cfd5b6fffffffffffffffffffffffffffffffff84166151c7816c0100000000000000000000000088615943565b90801561492c576c010000000000000000000000008709156151485760010180615148575f80fd5b9180856152148873ffffffffffffffffffffffffffffffffffffffff9860a095615c91565b615188565b615224858383615b34565b91615097565b620d89e86020820152614bf2565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276186020820152614bdf565b5060020b900360020b0260020b614bc7565b60019194939650600592955001938460020b60081d60010b5f520160205260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600160ff86161b0119905416908d8b831592831597885f146153c15750505050610330578f9160018f8f96907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276186060928f989560409660ff896fffffffffffffffffffffffffffffffff9a5f03166101e07f804040554300526644320000502061067405302602000010750620017611707760fc7fb6db6db6ddddddddd34d34d349249249210842108c6318c639ce739cffffffff840260f81c161b60f71c167e1f0d1e100c1d070f090b19131c1706010e11080a1a141802121b1503160405601f85851693831c63d76453e004161a17031660020b9060020b0160020b0260020b5b90614bc9565b90956fffffffffffffffffffffffffffffffff955060409450600193987ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618918960ff6060969b811681031660020b9060020b0160020b0260020b6153bb565b949891955099969298919598602088015160a01b76ffffff0000000000000000000000000000000000000000167fffffffffffffffffff000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8a51169216171782556fffffffffffffffffffffffffffffffff6003830154166fffffffffffffffffffffffffffffffff604089015116809103615535575b5082156155265760e060029101519101555b825190155f82121461551057506154ee6154f69293613785565b925103613785565b6fffffffffffffffffffffffffffffffff169060801b1793565b6154f69250906155209103613785565b91613785565b60e060019101519101556154d4565b6fffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffff000000000000000000000000000000006003840154161760038301555f6154c2565b5073ffffffffffffffffffffffffffffffffffffffff8c511673ffffffffffffffffffffffffffffffffffffffff60608501511614614adc565b60028b015494939094614acd565b7f9e4d7cc7000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b60449250604051917f7c9c6e8f00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b606083019073ffffffffffffffffffffffffffffffffffffffff825116818111156155ed5750505173ffffffffffffffffffffffffffffffffffffffff1673fffd8963efd1fc6a506488495d951d5263988d268110156155c25750614a75565b9a509a50509950505050505050505f925f929190565b5f85511315614a1a577f96206246000000000000000000000000000000000000000000000000000000005f5260045ffd5b62ffffff610fff89169116620f424081830204910103614a07565b508960d01c62ffffff166149fd565b610fff8860c41c169461499a565b90808202917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff828209918380841093039280840393847001000000000000000000000000000000001115610330571461577c57700100000000000000000000000000000000910990828211900360801b910360801c1790565b50505060801c90565b818102907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83820990828083109203918083039283620f424011156103305714615804577fde8f6cefed634549b62c77574f722e1ac57e23f24d8fd5cb790fb65668c2613993620f4240910990828211900360fa1b910360061c170290565b5050620f424091500490565b90808202917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff828209918380841093039280840393846c0100000000000000000000000011156103305714615881576c01000000000000000000000000910990828211900360a01b910360601c1790565b50505060601c90565b908160601b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6c01000000000000000000000000840992828085109403938085039485841115610330571461593c576c0100000000000000000000000082910981805f03168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b5091500490565b91818302917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8185099383808610950394808603958685111561033057146159da579082910981805f03168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b505091500490565b6fffffffffffffffffffffffffffffffff6c010000000000000000000000009173ffffffffffffffffffffffffffffffffffffffff80600195169116038060ff1d90810118931692615a348185615810565b93091515160190565b6fffffffffffffffffffffffffffffffff9073ffffffffffffffffffffffffffffffffffffffff8061364f9594169116038060ff1d908101189116615810565b9073ffffffffffffffffffffffffffffffffffffffff811673ffffffffffffffffffffffffffffffffffffffff831611615b2e575b73ffffffffffffffffffffffffffffffffffffffff8216928315615b22577bffffffffffffffffffffffffffffffff00000000000000000000000073ffffffffffffffffffffffffffffffffffffffff615b16948185169403169160601b16615c68565b90808206151591040190565b62bfc9215f526004601cfd5b90615ab2565b73ffffffffffffffffffffffffffffffffffffffff821673ffffffffffffffffffffffffffffffffffffffff821611615bd5575b73ffffffffffffffffffffffffffffffffffffffff8116918215615b225761364f937bffffffffffffffffffffffffffffffff00000000000000000000000073ffffffffffffffffffffffffffffffffffffffff615bd0948185169403169160601b16615943565b614922565b90615b68565b8015610330577f07060605060205000602030205040001060502050303040105050304000000006f8421084210842108cc6318c6db6d54be826fffffffffffffffffffffffffffffffff1060071b83811c67ffffffffffffffff1060061b1783811c63ffffffff1060051b1783811c61ffff1060041b1783811c60ff1060031b1792831c1c601f161a1790565b929190615c76828286615943565b93821561492c5709615c8457565b9060010190811561033057565b91908115615d02577bffffffffffffffffffffffffffffffff00000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9160601b169216918282029183838311918404141615615cf55761364f9261503092820391615c68565b63f5c787f15f526004601cfd5b505090565b90918015615d955773ffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffff000000000000000000000000819460601b16921680820281615d578483614922565b14615d7d575b5090615d6c615d719284614922565b612ffa565b80820615159104011690565b8301838110615d5d579150615d9192615c68565b1690565b50905090565b9073ffffffffffffffffffffffffffffffffffffffff82169182036130c85756fea164736f6c634300081a000a")
    };

    private byte[] _code;
    private long[] _bitmap;

    [Params(
        x0000_48KiB,
        x5b00_48KiB,
        x005b_256KiB,
        x5b5b_512KiB,
        x6500_48KiB,
        x6060_48KiB,
        x5b71_48KiB,
        x7f5b_256KiB,
        x5b7f_512KiB,
        SmallContract,
        MediumContract,
        UniSwapV4
    )]
    public string Scenario { get; set; }

    [GlobalSetup]
    public void Setup()
    {
        _code = _codeLookup[Scenario];
        _bitmap = JumpDestinationAnalyzer.CreateBitmap(_code.Length);
    }

    [Benchmark(Baseline = true)]
    public long[] Scalar()
        => JumpDestinationAnalyzer.PopulateJumpDestinationBitmap_Scalar(_bitmap, _code);

    //[Benchmark]
    //public long[] IndexOfAny()
    //    => PopulateJumpDestinationBitmap_IndexOfAny(_bitmap, _code);

    [Benchmark]
    public long[] Vector128()
        => JumpDestinationAnalyzer.PopulateJumpDestinationBitmap_Vector128(_bitmap, _code);

    [Benchmark]
    public long[] Vector512()
        => JumpDestinationAnalyzer.PopulateJumpDestinationBitmap_Vector512(_bitmap, _code);

    private static byte[] CreateCode(int size, byte byte0, byte byte1)
    {
        var array = new byte[size];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = i % 2 == 0 ? byte0 : byte1;
        }
        return array;
    }



    private static readonly SearchValues<byte> JumpAndPushes = SearchValues.Create(
    [
        (byte)Instruction.JUMPDEST,
        (byte)Instruction.PUSH1,
        (byte)Instruction.PUSH2,
        (byte)Instruction.PUSH3,
        (byte)Instruction.PUSH4,
        (byte)Instruction.PUSH5,
        (byte)Instruction.PUSH6,
        (byte)Instruction.PUSH7,
        (byte)Instruction.PUSH8,
        (byte)Instruction.PUSH9,
        (byte)Instruction.PUSH10,
        (byte)Instruction.PUSH11,
        (byte)Instruction.PUSH12,
        (byte)Instruction.PUSH13,
        (byte)Instruction.PUSH14,
        (byte)Instruction.PUSH15,
        (byte)Instruction.PUSH16,
        (byte)Instruction.PUSH17,
        (byte)Instruction.PUSH18,
        (byte)Instruction.PUSH19,
        (byte)Instruction.PUSH20,
        (byte)Instruction.PUSH21,
        (byte)Instruction.PUSH22,
        (byte)Instruction.PUSH23,
        (byte)Instruction.PUSH24,
        (byte)Instruction.PUSH25,
        (byte)Instruction.PUSH26,
        (byte)Instruction.PUSH27,
        (byte)Instruction.PUSH28,
        (byte)Instruction.PUSH29,
        (byte)Instruction.PUSH30,
        (byte)Instruction.PUSH31,
        (byte)Instruction.PUSH32,
    ]);

    [SkipLocalsInit]
    internal static long[] PopulateJumpDestinationBitmap_IndexOfAny(long[] bitmap, ReadOnlySpan<byte> code)
    {
        const int PUSH1 = (int)Instruction.PUSH1;
        const int JUMPDEST = (int)Instruction.JUMPDEST;

        int programCounter = 0;
        // Which 64‐bit segment we are currently accumulating flags for:
        int currentSegment = 0;
        // Bits within the current 64‐bit segment: a '1' means that byte index is a JUMPDEST.
        long currentFlags = 0;
        while (programCounter < code.Length)
        {
            // Look for the next byte that is either JUMPDEST or some PUSHx.
            ReadOnlySpan<byte> remainder = code.Slice(programCounter);
            int relativeIndex = remainder.IndexOfAny(JumpAndPushes);
            if (relativeIndex < 0)
            {
                // No more JUMPDEST or PUSH-opcodes in the rest of the code.
                break;
            }

            int opPosition = programCounter + relativeIndex;
            int segmentAtOp = opPosition >> 6;

            // If we jumped into a new 64‐bit segment, flush the old flags first.
            if (segmentAtOp != currentSegment)
            {
                if (currentFlags != 0)
                {
                    // Use the last programCounter (which is still in the old segment)
                    // so that (lastProgramCounter >> 6) == currentSegment.
                    MarkJumpDestinations(bitmap, programCounter, currentFlags);
                    currentFlags = 0;
                }

                currentSegment = segmentAtOp;
            }

            int op = code[opPosition];
            int move;

            if (op == JUMPDEST)
            {
                // Mark the bit for this JUMPDEST within its 64‐bit segment
                int bitIndex = opPosition & 63;
                currentFlags |= (1L << bitIndex);

                // We only need to advance by 1 byte for a JUMPDEST
                move = 1;
            }
            else
            {
                // We know 'op' is one of PUSH1..PUSH32 because of IndexOfAny(JumpAndPushes).
                // The push‐immediate length = (opcode - PUSH1) + 1.
                // Plus 1 byte for the opcode itself ⇒ total = (opcode - PUSH1 + 2).
                move = (op - PUSH1) + 2;
            }

            int offsetInSegment = opPosition & 63;
            int nextOffsetInSegment = offsetInSegment + move;
            int nextPosition = opPosition + move;
            bool exit = nextPosition >= code.Length;

            // If we cross the 64‐bit‐word boundary, flush this segment’s flags now.
            if (nextOffsetInSegment >= 64 || exit)
            {
                if (currentFlags != 0)
                {
                    // When flushing, we use opPosition (which is still in 'currentSegment')
                    // so that (opPosition >> 6) == currentSegment.
                    MarkJumpDestinations(bitmap, opPosition, currentFlags);
                    currentFlags = 0;
                }
            }

            programCounter = nextPosition;
        }

        // After exiting the loop, if there are any remaining bits in currentFlags, flush them.
        if (currentFlags != 0)
        {
            // We know currentFlags belongs to segment 'currentSegment'.
            // Passing any index whose (index >> 6) == currentSegment is fine.
            int flushPosition = currentSegment << 6;
            MarkJumpDestinations(bitmap, flushPosition, currentFlags);
        }

        return bitmap;

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static void MarkJumpDestinations(long[] jumpDestinationBitmap, int pos, long flags)
        {
            const int BitShiftPerInt64 = 6;
            uint offset = (uint)pos >> BitShiftPerInt64;
            Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(jumpDestinationBitmap), offset) |= flags;
        }
    }
}
